﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using Aga.Controls.Tree;
using System.Reflection;

namespace UnrealDebugger.Panels
{
    public partial class FileSearchPanel : Panel
    {
        public class SearchNode : Node
        {
            public SearchNode()
                : base()
            {
            }

            public SearchNode(string text)
                : base(text)
            {
            }

            public int FilesFound { get; set; }
            public string Name { get { return "[" + FilesFound.ToString() + " files found]"; } }
        }

        public class ResultNode : Node
        {
            public ResultNode()
                : base()
            {
            }

            public ResultNode(string text)
                : base(text)
            {
            }

            public bool IsUnrealFile()
            {
                if (File != null)
                {
                    return (string.Compare(File.Extension, ".uc", true) == 0) || (string.Compare(File.Extension, ".uci", true) == 0);
                }

                return false;
            }

            public FileInfo File { get; set; }
            public string Name { get { return File != null ? File.Name : ""; } }
            public string Path { get { return File != null ? File.FullName : ""; } }
            public Image Icon { get { return IsUnrealFile() ? _script : _file; } }

            protected static Image _file = null;
            protected static Image _script = null;

            static ResultNode()
            {
                Stream file = null;
                Assembly assembly = typeof(ResultNode).Assembly;

                file = assembly.GetManifestResourceStream("UnrealDebugger.Resources.File.png");
                _file = Image.FromStream(file);

                file = assembly.GetManifestResourceStream("UnrealDebugger.Resources.Script.png");
                _script = Image.FromStream(file);
            }
        }

        private TreeModel _model = new TreeModel();

        public FileSearchPanel()
            : base()
        {
            InitializeComponent();
            this.Load += new EventHandler(OnLoad);
        }

        public void FocusInput()
        {
            this.textBoxSearch.SelectAll();
            this.textBoxSearch.Focus();
        }

        private void OnLoad(object sender, EventArgs e)
        {
            this.treeViewResults.Model = _model;
        }

        internal void GotoLine()
        {
            foreach (TreeNodeAdv node in this.treeViewResults.SelectedNodes)
            {
                ResultNode searchNode = node.Tag as ResultNode;
                FileInfo f = searchNode != null ? searchNode.File : null;

                if (f != null)
                {
                    Document doc = UnrealDebuggerIDE.Instance.GetDocumentFromFile(f.FullName);
                    UnrealDebuggerIDE.Instance.ShowDocument(doc);
                }
            }
        }

        private void textBoxSearch_TextChanged(object sender, EventArgs e)
        {
            List<FileInfo> files = UnrealDebuggerIDE.Instance.SearchFiles(this.textBoxSearch.Text);

            this.SuspendLayout();
            this.treeViewResults.BeginUpdate();
            this._model.Nodes.Clear();

            if (files.Count < 250)
            {
                files.Sort(delegate(FileInfo a, FileInfo b) { return string.Compare(a.Name, b.Name, true); });

                foreach (FileInfo file in files)
                {
                    bool isScript = (string.Compare(file.Extension, ".uc", true) == 0) ||
                        (string.Compare(file.Extension, ".uci", true) == 0);

                    ResultNode node = new ResultNode(file.Name);
                    node.File = file;
                    this._model.Nodes.Add(node);
                }
            }
            else if (files.Count > 0)
            {
                SearchNode node = new SearchNode();
                node.FilesFound = files.Count;
                this._model.Nodes.Add(node);
            }

            this.treeViewResults.EndUpdate();
            this.ResumeLayout();
        }

        private void treeViewResults_DoubleClick(object sender, EventArgs e)
        {
            GotoLine();
        }

        private void treeViewResults_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Return)
            {
                GotoLine();
            }
        }

        private void textBoxSearch_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Return)
            {
                if (this.treeViewResults.Root.Children.Count > 0)
                {
                    this.treeViewResults.SelectedNode = this.treeViewResults.Root.Children[0];
                    this.treeViewResults.Focus();
                }
            }
        }
    }
}
